package com.pxmeta.user.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.pxmeta.chat.service.HuanxinService;
import com.pxmeta.common.constant.HttpStatus;
import com.pxmeta.common.exception.ServiceException;
import com.pxmeta.dynamic.entity.enums.MailInteractiveTypeEnum;
import com.pxmeta.dynamic.service.IMailService;
import com.pxmeta.user.converter.UserConverter;
import com.pxmeta.user.entity.User;
import com.pxmeta.user.entity.UserFollow;
import com.pxmeta.user.entity.dto.UserDTO;
import com.pxmeta.user.mapper.UserFollowMapper;
import com.pxmeta.user.mapper.UserMapper;
import com.pxmeta.user.service.IUserService;
import com.pxmeta.user.service.IUserFollowService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wcl
 * @since 2022-07-07
 */
@Service
@RequiredArgsConstructor
public class UserFollowServiceImpl extends ServiceImpl<UserFollowMapper, UserFollow> implements IUserFollowService {

    private final HuanxinService huanxinService;

    private final UserMapper userMapper;
    private final IMailService mailService;
    /**
     * 关注用户
     * @param userId
     * @param followUserId
     * @param circleId
     */
    @Override
    public void followUser(Long userId, Long followUserId,Long circleId) {
        boolean follow = isFollow(userId, followUserId);
        if (follow){
            throw new ServiceException("请勿重复关注！",HttpStatus.PARAMS_ERROR);
        }
        UserFollow userFollow = new UserFollow();
        userFollow.setFollowUserId(followUserId);
        userFollow.setUserId(userId);
        userFollow.setCircleId(circleId);
        //关注后成为好友。
        User user = userMapper.selectById(userId);
        User followUser = userMapper.selectById(followUserId);
        if (null == followUser){
            throw new ServiceException("该用户已注销！",HttpStatus.USER_CANCEL_ERROR);
        }
        huanxinService.addFriend(user.getUsername(),followUser.getUsername());
        this.save(userFollow);

        mailService.sendInteractFollowMessage(MailInteractiveTypeEnum.FOLLOW.getType(),userId, followUserId,circleId);

    }

    /**
     * 查询是否关注
     * @param userId
     * @param followUserId
     * @return
     */
    @Override
    public boolean isFollow(Long userId, Long followUserId) {
        LambdaQueryWrapper<UserFollow> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserFollow::getUserId, userId)
                .eq(UserFollow::getFollowUserId, followUserId);
        UserFollow one = this.getOne(wrapper);
        return one != null;
    }

    /**
     * 取消关注
     * @param userId
     * @param followUserId
     */
    @Override
    public void unFollowUser(Long userId, Long followUserId) {
        LambdaQueryWrapper<UserFollow> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserFollow::getUserId, userId)
                .eq(UserFollow::getFollowUserId, followUserId);
        UserFollow uf = this.getOne(wrapper);
        if (null == uf){
            throw new ServiceException("你还没有关注！",HttpStatus.PARAMS_ERROR);
        }
        User user = userMapper.selectById(userId);
        User followUser = userMapper.selectById(followUserId);
        huanxinService.removeFriend(user.getUsername(),followUser.getUsername());
        this.removeById(uf);
    }


    /**
     * 获取关注用户列表
     * @param userId
     * @return
     */
    @Override
    public List<UserDTO> getFollowUsers(Long userId, Integer page, Integer size) {
        List<User> users = baseMapper.getFollowUsers(userId, new Page(page,size));
        return UserConverter.toDtoList(users);
    }

    @Override
    public List<UserDTO> getFansUsers(Long userId, Integer page, Integer size) {
        LambdaQueryWrapper<UserFollow> wrapper = Wrappers.lambdaQuery();
        List<User> users = baseMapper.getFansUsers(userId, new Page(page,size));
        if (users.isEmpty()){
            return Lists.newArrayList();
        }
        //是否互相关注
        List<Long> fansUserIds = users.stream().map(User::getId).collect(Collectors.toList());
        wrapper.in(UserFollow::getFollowUserId, fansUserIds)
                .eq(UserFollow::getUserId, userId);

        List<Long> friendUserIds = this.list(wrapper).stream().map(UserFollow::getFollowUserId).collect(Collectors.toList());
        List<UserDTO> userDTOS = UserConverter.toDtoList(users);

        return userDTOS;
    }

    @Override
    public List<UserDTO> getFriendUsers(Long userId, Integer page, Integer size, String keyword, Long circleId, List<String> excludeUsernameList) {
        List<User> friendUsers = baseMapper.getFriendUsers(userId, keyword, new Page<>(page, size), circleId, excludeUsernameList);

        return UserConverter.toDtoList(friendUsers);
    }

    @Override
    public Long getFollowCount(Long userId) {
        LambdaQueryWrapper<UserFollow> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserFollow::getUserId, userId);
        return this.count(wrapper);
    }

    @Override
    public Long getFansCount(Long userId) {
        LambdaQueryWrapper<UserFollow> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserFollow::getFollowUserId, userId);
        return this.count(wrapper);
    }

    @Override
    public List<UserDTO> getChatGroupInviters(Long userId, Integer page, Integer size, String keyword, Long chatGroupId) {

        JSONArray users = huanxinService.getUserPage(chatGroupId.toString(), page, size);

        List<String> usernameList = Lists.newLinkedList();
        for (Object user : users) {
            String userStr = JSONObject.toJSONString(user);
            JSONObject jsonObj = JSONObject.parseObject(userStr);
            Set<Map.Entry<String, Object>> entries = jsonObj.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                Object value = entry.getValue();
                usernameList.add(value.toString());
            }
        }

       return this.getFriendUsers(userId, page, size, keyword, null, usernameList);

    }


}
